﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 开关控件
    /// </summary>
    [Description("开关控件")]
    [DefaultProperty("IsOn")]
    [DefaultEvent("Toggled")]
    [TypeConverter(typeof(PropertyOrderConverter))]
    [Designer(typeof(ToggleSwitchDesigner))]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(ToggleSwitch), "Controls.ToggleSwitch.Resources.ToggleSwitch.bmp")]
    public class ToggleSwitch : MainThreadAnimationControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(ToggleSwitch)).GetName().Name, typeof(ToggleSwitch).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled= SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 新增事件

        public delegate void EventToggleingEventHandler(object sender, CancelEventArgs e);
        private static readonly object EventToggleing = new object();
        /// <summary>
        /// 开关状态更改中事件
        /// </summary>
        [Description("开关状态更改中事件")]
        public event EventToggleingEventHandler Toggleing
        {
            add { Events.AddHandler(EventToggleing, value); }
            remove { Events.RemoveHandler(EventToggleing, value); }
        }

        private static readonly object EventToggled = new object();
        /// <summary>
        /// 开关状态更改后事件
        /// </summary>
        [Description("开关状态更改后事件")]
        public event EventHandler Toggled
        {
            add { Events.AddHandler(EventToggled, value); }
            remove { Events.RemoveHandler(EventToggled, value); }
        }

        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PaddingChanged
        {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler FontChanged
        {
            add { base.FontChanged += value; }
            remove { base.FontChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TextChanged
        {
            add { base.TextChanged += value; }
            remove { base.TextChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackColorChanged
        {
            add { base.BackColorChanged += value; }
            remove { base.BackColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }
        #endregion

        #region 新增属性

        private ToggleSwitchStylePattern stylePattern = ToggleSwitchStylePattern.Default;
        /// <summary>
        /// 风格模式
        /// </summary>
        [Description("风格模式")]
        [Category("杂项")]
        [PropertyOrder(-198)]
        [DefaultValue(ToggleSwitchStylePattern.Default)]
        public ToggleSwitchStylePattern StylePattern
        {
            get { return this.stylePattern; }
            set
            {
                if (this.stylePattern == value)
                    return;

                this.stylePattern = value;
                if (this.slideing)
                {
                    MainThreadAnimationControl.AnimationStop(this);
                    this.slideing = false;
                    this.usedTime = 0;
                }
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private bool readOnly = false;
        /// <summary>
        /// 是否只读
        /// </summary>
        [Description("是否只读")]
        [Category("杂项")]
        [PropertyOrder(-196)]
        [DefaultValue(false)]
        public bool ReadOnly
        {
            get { return this.readOnly; }
            set
            {
                if (this.readOnly == value)
                    return;

                this.readOnly = value;
                if (this.readOnly && this.Focused)
                {
                    this.mousedowntype = MouseButtons.None;
                    IContainerControl c = this.Parent.GetContainerControl();
                    if (c != null)
                    {
                        ((Control)c).SelectNextControl(this, true, true, true, true);
                    }
                    this.Invalidate();
                }
            }
        }

        private bool isOn = false;
        /// <summary>
        /// 开关状态
        /// </summary>
        [Description("开关状态")]
        [Category("杂项")]
        [PropertyOrder(-193)]
        [DefaultValue(false)]
        public bool IsOn
        {
            get { return this.isOn; }
            set
            {
                if (this.isOn == value)
                    return;

                if (this.DesignMode)
                {
                    this.isOn = value;
                    this.InitializeElement();
                    this.Invalidate();
                }
                else
                {
                    CancelEventArgs arg = new CancelEventArgs(false);
                    this.OnToggleing(arg);
                    if (arg.Cancel)
                    {
                        return;
                    }

                    this.isOn = value;
                    if (this.slideing)
                    {
                        MainThreadAnimationControl.AnimationStop(this);
                        this.slideing = false;
                        this.usedTime = 0;
                    }
                    this.InitializeElement();
                    this.Invalidate();

                    this.OnToggled(EventArgs.Empty);
                }

            }
        }

        private string offText = "OFF";
        /// <summary>
        /// 关闭状态文本
        /// </summary>
        [Description("关闭状态文本")]
        [Category("杂项")]
        [PropertyOrder(-191)]
        [DefaultValue("OFF")]
        public string OffText
        {
            get { return this.offText; }
            set
            {
                if (this.offText == value)
                    return;

                this.offText = value;
                this.SetBoundsCore(this.Location.X, this.Location.Y, this.Width + 1, this.Height + 1, BoundsSpecified.Size);
            }
        }

        private string onText = "ON";
        /// <summary>
        /// 开启状态文本
        /// </summary>
        [Description("开启状态文本")]
        [Category("杂项")]
        [PropertyOrder(-188)]
        [DefaultValue("ON")]
        public string OnText
        {
            get { return this.onText; }
            set
            {
                if (this.onText == value)
                    return;

                this.onText = value;
                this.SetBoundsCore(this.Location.X, this.Location.Y, this.Width + 1, this.Height + 1, BoundsSpecified.Size);
            }
        }

        #endregion

        #region 重写属性

        protected override Size DefaultSize
        {
            get { return new Size(90, 40); }
        }

        public new Font Font
        {
            get { return base.Font; }
            set
            {
                base.Font = value;
                this.SetBoundsCore(this.Location.X, this.Location.Y, this.Width + 1, this.Height + 1, BoundsSpecified.Size);
            }
        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Disable; }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Padding Padding
        {
            get { return base.Padding; }
            set { base.Padding = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get { return base.Text; }
            set { base.Text = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
            get { return this.StyleAppearance.BackColor; }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get { return this.StyleAppearance.Off.Normal.ThumbBackColor; }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 鼠标按下类型
        /// </summary>
        private MouseButtons mousedowntype = MouseButtons.None;

        /// <summary>
        /// 存放Switch信息
        /// </summary>
        private ToggleSwitchBody toggleSwitchBody = new ToggleSwitchBody();

        /// <summary>
        /// 动画中
        /// </summary>
        private bool slideing = false;

        // 滑块动画消耗时间(毫秒)
        private int allTime = 150;
        /// <summary>
        /// 动画已使用的时间
        /// </summary>
        private double usedTime = 0;

        #endregion

        public ToggleSwitch()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, false);//自定义单击事件逻辑
            SetStyle(ControlStyles.StandardDoubleClick, false);//停用双加事件

            this.InitializeElement();
            this.OnSkinChanged();

        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;

            Color bar_color = Color.Empty;
            Color slide_color = Color.Empty;
            StyleAppearanceObject.StateAppearanceObject stateAppearance = this.IsOn ? this.StyleAppearance.On : this.StyleAppearance.Off;
            if (!this.Enabled)
            {
                bar_color = stateAppearance.Disabled.TrackBackColor;
                slide_color = stateAppearance.Disabled.ThumbBackColor;
            }
            else
            {
                bar_color = stateAppearance.Normal.TrackBackColor;
                slide_color = stateAppearance.Normal.ThumbBackColor;
            }

            if (this.StylePattern == ToggleSwitchStylePattern.Default)
            {
                //背景
                SolidBrush bar_sb = new SolidBrush(bar_color);
                g.FillRectangle(bar_sb, this.toggleSwitchBody.bar_rect);
                bar_sb.Dispose();

                //滑块
                g.SmoothingMode = SmoothingMode.AntiAlias;
                SolidBrush slide_sb = new SolidBrush(slide_color);
                g.FillEllipse(slide_sb, this.toggleSwitchBody.slide_current_rect);
                slide_sb.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    int activate_border_margin = 3;
                    RectangleF activate_border_rect = new RectangleF(this.toggleSwitchBody.slide_current_rect.X + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Y + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Width - activate_border_margin * 2, this.toggleSwitchBody.slide_current_rect.Height - activate_border_margin * 2);
                    Pen activate_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawEllipse(activate_pen, activate_border_rect);
                    activate_pen.Dispose();
                }
            }
            else if (this.StylePattern == ToggleSwitchStylePattern.CircularChar)
            {
                //背景
                g.SmoothingMode = SmoothingMode.AntiAlias;
                Pen bar_pen = new Pen(bar_color, this.toggleSwitchBody.bar_rect.Height) { StartCap = LineCap.Round, EndCap = LineCap.Round };
                g.DrawLine(bar_pen, new Point(this.toggleSwitchBody.bar_rect.X + this.toggleSwitchBody.bar_rect.Height / 2, this.toggleSwitchBody.bar_rect.Y + this.toggleSwitchBody.bar_rect.Height / 2), new Point(this.toggleSwitchBody.bar_rect.Right - this.toggleSwitchBody.bar_rect.Height / 2, this.toggleSwitchBody.bar_rect.Y + this.toggleSwitchBody.bar_rect.Height / 2));
                bar_pen.Dispose();

                //背景符号
                float bar_char_min_grid = this.toggleSwitchBody.slide_off_rect.Height / 12f;
                Pen bar_char_pen = new Pen(slide_color, bar_char_min_grid);

                PointF[] box_char_line = new PointF[] {
                        new PointF(this.toggleSwitchBody.slide_off_rect.X+bar_char_min_grid*4.5f,this.toggleSwitchBody.slide_off_rect.Y+ bar_char_min_grid * 6),
                        new PointF(this.toggleSwitchBody.slide_off_rect.X+bar_char_min_grid *6,this.toggleSwitchBody.slide_off_rect.Y+  bar_char_min_grid * 7.5f),
                        new PointF(this.toggleSwitchBody.slide_off_rect.X+bar_char_min_grid*8.7f ,this.toggleSwitchBody.slide_off_rect.Y+  bar_char_min_grid*4.5f)
                        };
                g.DrawLines(bar_char_pen, box_char_line);

                PointF line_left_s = new PointF(this.toggleSwitchBody.slide_on_rect.X + bar_char_min_grid * 4, this.toggleSwitchBody.slide_on_rect.Y + bar_char_min_grid * 4);
                PointF line_left_e = new PointF(this.toggleSwitchBody.slide_on_rect.X + bar_char_min_grid * 8, this.toggleSwitchBody.slide_on_rect.Y + bar_char_min_grid * 8);
                g.DrawLine(bar_char_pen, line_left_s, line_left_e);

                PointF line_right_s = new PointF(this.toggleSwitchBody.slide_on_rect.X + bar_char_min_grid * 8, this.toggleSwitchBody.slide_on_rect.Y + bar_char_min_grid * 4);
                PointF line_right_e = new PointF(this.toggleSwitchBody.slide_on_rect.X + bar_char_min_grid * 4, this.toggleSwitchBody.slide_on_rect.Y + bar_char_min_grid * 8);
                g.DrawLine(bar_char_pen, line_right_s, line_right_e);

                bar_char_pen.Dispose();

                //滑块
                SolidBrush slide_sb = new SolidBrush(slide_color);
                g.FillEllipse(slide_sb, this.toggleSwitchBody.slide_current_rect);
                slide_sb.Dispose();
                Pen slide_border_pen = new Pen(bar_color);
                g.DrawEllipse(slide_border_pen, this.toggleSwitchBody.slide_current_rect);
                slide_border_pen.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    int activate_border_margin = 3;
                    RectangleF activate_border_rect = new RectangleF(this.toggleSwitchBody.slide_current_rect.X + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Y + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Width - activate_border_margin * 2, this.toggleSwitchBody.slide_current_rect.Height - activate_border_margin * 2);
                    Pen activate_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawEllipse(activate_pen, activate_border_rect);
                    activate_pen.Dispose();
                }
            }
            else if (this.StylePattern == ToggleSwitchStylePattern.CircularZoom)
            {
                //背景
                g.SmoothingMode = SmoothingMode.AntiAlias;
                Pen bar_pen = new Pen(bar_color, this.toggleSwitchBody.bar_rect.Height) { StartCap = LineCap.Round, EndCap = LineCap.Round };
                g.DrawLine(bar_pen, new Point(this.toggleSwitchBody.bar_rect.X + this.toggleSwitchBody.bar_rect.Height / 2, this.toggleSwitchBody.bar_rect.Y + this.toggleSwitchBody.bar_rect.Height / 2), new Point(this.toggleSwitchBody.bar_rect.Right - this.toggleSwitchBody.bar_rect.Height / 2, this.toggleSwitchBody.bar_rect.Y + this.toggleSwitchBody.bar_rect.Height / 2));
                bar_pen.Dispose();

                //滑块
                SolidBrush slide_sb = new SolidBrush(slide_color);
                g.FillEllipse(slide_sb, this.toggleSwitchBody.slide_current_rect);
                slide_sb.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    int activate_border_margin = 3;
                    RectangleF activate_border_rect = new RectangleF(this.toggleSwitchBody.slide_current_rect.X + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Y + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Width - activate_border_margin * 2, this.toggleSwitchBody.slide_current_rect.Height - activate_border_margin * 2);
                    Pen activate_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawEllipse(activate_pen, activate_border_rect);
                    activate_pen.Dispose();
                }
            }
            else if (this.StylePattern == ToggleSwitchStylePattern.FlatText)
            {
                NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);

                SolidBrush bar_sb = new SolidBrush(bar_color);
                SolidBrush slide_sb = new SolidBrush(slide_color);

                //背景
                g.FillRectangle(bar_sb, this.toggleSwitchBody.bar_rect);

                //背景文本
                SizeF off_text_size = new SizeF((int)Math.Ceiling(g.MeasureString(this.OffText, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                g.DrawString(this.OffText, this.Font, slide_sb, this.toggleSwitchBody.slide_off_rect.X + (this.toggleSwitchBody.slide_off_rect.Width - off_text_size.Width) / 2, this.toggleSwitchBody.slide_off_rect.Y + (this.toggleSwitchBody.slide_off_rect.Height - off_text_size.Height) / 2, StringFormat.GenericTypographic);
                SizeF on_text_size = new SizeF((int)Math.Ceiling(g.MeasureString(this.OnText, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width), font_metrics.GetFontRealHeight());
                g.DrawString(this.OnText, this.Font, slide_sb, this.toggleSwitchBody.slide_on_rect.X + (this.toggleSwitchBody.slide_on_rect.Width - on_text_size.Width) / 2, this.toggleSwitchBody.slide_on_rect.Y + (this.toggleSwitchBody.slide_on_rect.Height - on_text_size.Height) / 2, StringFormat.GenericTypographic);

                //滑块
                g.FillRectangle(slide_sb, this.toggleSwitchBody.slide_current_rect);

                //滑块竖线
                float avg_w = this.toggleSwitchBody.slide_current_rect.Width / 10f;
                float avg_h = this.toggleSwitchBody.slide_current_rect.Height / 5f;

                RectangleF slideline_left_rectf = new RectangleF();
                slideline_left_rectf.Width = avg_w;
                slideline_left_rectf.Height = avg_h * 3;
                slideline_left_rectf.X = this.toggleSwitchBody.slide_current_rect.X + avg_w * 3;
                slideline_left_rectf.Y = this.toggleSwitchBody.slide_current_rect.Y + avg_h;

                RectangleF slideline_right_rectf = new RectangleF();
                slideline_right_rectf.Width = avg_w;
                slideline_right_rectf.Height = avg_h * 3;
                slideline_right_rectf.X = slideline_left_rectf.Right + avg_w * 2;
                slideline_right_rectf.Y = slideline_left_rectf.Y;

                g.FillRectangle(bar_sb, slideline_left_rectf);
                g.FillRectangle(bar_sb, slideline_right_rectf);

                bar_sb.Dispose();
                slide_sb.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    int activate_border_margin = 3;
                    Rectangle activate_border_rect = new Rectangle(this.toggleSwitchBody.slide_current_rect.X + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Y + activate_border_margin, this.toggleSwitchBody.slide_current_rect.Width - activate_border_margin * 2, this.toggleSwitchBody.slide_current_rect.Height - activate_border_margin * 2);
                    Pen activate_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawRectangle(activate_pen, activate_border_rect);
                    activate_pen.Dispose();
                }
            }

        }

        protected override void Select(bool directed, bool forward)
        {
            if (this.ReadOnly && this.Parent != null)
            {
                IContainerControl c = this.Parent.GetContainerControl();
                if (c != null)
                {
                    ((Control)c).SelectNextControl(this, true, true, true, true);
                }
                return;
            }



            base.Select(directed, forward);
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);

            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);

            this.mousedowntype = MouseButtons.None;
            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            this.mousedowntype = MouseButtons.None;
            if (this.slideing)
            {
                MainThreadAnimationControl.AnimationStop(this);
                this.slideing = false;
                this.usedTime = 0;
                this.toggleSwitchBody.slide_current_rect = this.IsOn ? this.toggleSwitchBody.slide_on_rect : this.toggleSwitchBody.slide_off_rect;
                this.Invalidate();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            this.mousedowntype = MouseButtons.None;
            if (this.slideing)
            {
                MainThreadAnimationControl.AnimationStop(this);
                this.slideing = false;
                this.usedTime = 0;
                this.toggleSwitchBody.slide_current_rect = this.IsOn ? this.toggleSwitchBody.slide_on_rect : this.toggleSwitchBody.slide_off_rect;
                this.Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            this.mousedowntype = MouseButtons.None;
            if (this.slideing)
            {
                MainThreadAnimationControl.AnimationStop(this);
                this.slideing = false;
                this.usedTime = 0;
                this.toggleSwitchBody.slide_current_rect = this.IsOn ? this.toggleSwitchBody.slide_on_rect : this.toggleSwitchBody.slide_off_rect;
                this.Invalidate();
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (this.ReadOnly)
                return;

            if (!this.Focused)
            {
                this.Focus();
            }

            this.mousedowntype |= e.Button;

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (this.ReadOnly)
                return;

            if (e.Button == MouseButtons.Left)
            {
                if (this.mousedowntype.HasFlag(MouseButtons.Left) && this.ClientRectangle.Contains(e.Location))
                {
                    this.SetState();
                }
            }

            this.mousedowntype &= ~e.Button;

            base.OnMouseUp(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.Space:
                    {
                        if (!this.ReadOnly)
                        {
                            this.SetState();
                        }
                        break;
                    }
            }

            base.OnKeyUp(e);
        }

        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            Size control_size = this.GetControlAutoSize();

            base.SetBoundsCore(x, y, control_size.Width, control_size.Height, specified);

            if (this.slideing)
            {
                MainThreadAnimationControl.AnimationStop(this);
                this.slideing = false;
                this.usedTime = 0;
            }
            this.InitializeElement();
            this.Invalidate();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                MainThreadAnimationControl.AnimationStop(this);
                this.slideing = false;
            }
            base.Dispose(disposing);
        }

        /// <summary>
        /// 动画控件动画中要处理的内容(不能时耗时操作)
        /// </summary>
        /// <param name="interval">动画定时器间隔时间</param>
        protected override void Animationing(int interval)
        {
            this.usedTime += interval;
            if (this.usedTime > this.allTime)
            {
                this.usedTime = this.allTime;
                MainThreadAnimationControl.AnimationStop(this);
                this.slideing = false;
            }

            double progress = AnimationHelper.EaseOut(this.usedTime, this.allTime, 2.0);
            if (this.slideing == false)
            {
                if (progress < 0)
                    progress = 0;
                if (progress > 1)
                    progress = 1;

                this.usedTime = 0;
            }

            if (this.IsOn)
            {
                int x = (int)(this.toggleSwitchBody.slide_prepare_rect.X + (this.toggleSwitchBody.slide_on_rect.X - this.toggleSwitchBody.slide_prepare_rect.X) * progress);
                this.toggleSwitchBody.slide_current_rect = new Rectangle(x, this.toggleSwitchBody.slide_current_rect.Y, this.toggleSwitchBody.slide_current_rect.Width, this.toggleSwitchBody.slide_current_rect.Height);
            }
            else
            {
                int x = (int)(this.toggleSwitchBody.slide_prepare_rect.X - (this.toggleSwitchBody.slide_prepare_rect.X - this.toggleSwitchBody.slide_off_rect.X) * progress);
                this.toggleSwitchBody.slide_current_rect = new Rectangle(x, this.toggleSwitchBody.slide_current_rect.Y, this.toggleSwitchBody.slide_current_rect.Width, this.toggleSwitchBody.slide_current_rect.Height);
            }

            if (StylePattern == ToggleSwitchStylePattern.CircularZoom)
            {
                if (this.IsOn)
                {
                    int y = (int)Math.Ceiling(this.toggleSwitchBody.slide_prepare_rect.Y + (this.toggleSwitchBody.slide_on_rect.Y - this.toggleSwitchBody.slide_prepare_rect.Y) * progress);
                    int w = (int)Math.Ceiling(this.toggleSwitchBody.slide_prepare_rect.Width + (this.toggleSwitchBody.slide_on_rect.Width - this.toggleSwitchBody.slide_prepare_rect.Width) * progress);
                    int h = this.toggleSwitchBody.slide_current_rect.Width;
                    this.toggleSwitchBody.slide_current_rect = new Rectangle(this.toggleSwitchBody.slide_current_rect.X, y, w, h);
                }
                else
                {
                    int y = (int)Math.Ceiling(this.toggleSwitchBody.slide_prepare_rect.Y - (this.toggleSwitchBody.slide_prepare_rect.Y - this.toggleSwitchBody.slide_off_rect.Y) * progress);
                    int w = (int)Math.Ceiling(this.toggleSwitchBody.slide_prepare_rect.Width - (this.toggleSwitchBody.slide_prepare_rect.Width - this.toggleSwitchBody.slide_off_rect.Width) * progress);
                    int h = this.toggleSwitchBody.slide_current_rect.Width;
                    this.toggleSwitchBody.slide_current_rect = new Rectangle(this.toggleSwitchBody.slide_current_rect.X, y, w, h);
                }
            }
            this.Invalidate();
        }

        #endregion

        #region 虚方法

        protected virtual void OnToggleing(CancelEventArgs e)
        {
            EventToggleingEventHandler handler = Events[EventToggleing] as EventToggleingEventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnToggled(EventArgs e)
        {
            EventHandler handler = Events[EventToggled] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 初始化控件内部元素布局
        /// </summary>
        public void InitializeElement()
        {

            NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);
            if (this.StylePattern == ToggleSwitchStylePattern.Default)
            {
                int slide_width = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 3;
                int slide_height = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 3;
                int bar_height = slide_height / 6;

                this.toggleSwitchBody.bar_rect = new Rectangle(this.ClientRectangle.X + (int)(font_metrics.GetFontStereotypesMargim() * 1.5) + slide_width / 3, this.ClientRectangle.Y + (int)Math.Ceiling((this.ClientRectangle.Height - bar_height) / 2f), this.ClientRectangle.Width - font_metrics.GetFontStereotypesMargim() * 3 - slide_width * 2 / 3, bar_height);
                this.toggleSwitchBody.slide_off_rect = new Rectangle(this.ClientRectangle.X + (int)(font_metrics.GetFontStereotypesMargim() * 1.5), this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_height) / 2, slide_width, slide_height);
                this.toggleSwitchBody.slide_on_rect = new Rectangle(this.ClientRectangle.Right - (int)(font_metrics.GetFontStereotypesMargim() * 1.5) - slide_width, this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_height) / 2, slide_width, slide_height);
            }
            else if (this.StylePattern == ToggleSwitchStylePattern.CircularChar)
            {
                int slide_width = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 3;
                int slide_height = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 3;

                this.toggleSwitchBody.bar_rect = new Rectangle(this.ClientRectangle.X + (int)(font_metrics.GetFontStereotypesMargim() * 1.5), this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_height) / 2, this.ClientRectangle.Width - font_metrics.GetFontStereotypesMargim() * 3, slide_height);
                this.toggleSwitchBody.slide_off_rect = new Rectangle(this.ClientRectangle.X + (int)(font_metrics.GetFontStereotypesMargim() * 1.5), this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_height) / 2, slide_width, slide_height);
                this.toggleSwitchBody.slide_on_rect = new Rectangle(this.ClientRectangle.Right - (int)(font_metrics.GetFontStereotypesMargim() * 1.5) - slide_width, this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_height) / 2, slide_width, slide_height);
            }
            else if (this.StylePattern == ToggleSwitchStylePattern.CircularZoom)
            {
                int slide_off_width = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 3;
                int slide_off_height = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 3;
                int slide_on_width = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 5;
                int slide_on_height = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 5;

                this.toggleSwitchBody.bar_rect = new Rectangle(this.ClientRectangle.X + (int)(font_metrics.GetFontStereotypesMargim() * 1.5), this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_off_height) / 2, this.ClientRectangle.Width - font_metrics.GetFontStereotypesMargim() * 3, slide_off_height);
                this.toggleSwitchBody.slide_off_rect = new Rectangle(this.ClientRectangle.X + (int)(font_metrics.GetFontStereotypesMargim() * 1.5), this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_off_height) / 2, slide_off_width, slide_off_height);
                this.toggleSwitchBody.slide_on_rect = new Rectangle(this.ClientRectangle.Right - (int)(font_metrics.GetFontStereotypesMargim() * 1.5) - font_metrics.GetFontStereotypesMargim() - slide_on_width, this.ClientRectangle.Y + (this.ClientRectangle.Height - slide_on_height) / 2, slide_on_width, slide_on_height);
            }
            else if (this.StylePattern == ToggleSwitchStylePattern.FlatText)
            {
                int slide_width = (this.ClientRectangle.Width - font_metrics.GetFontStereotypesMargim() * 5) / 2;
                int slide_height = this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 4;

                this.toggleSwitchBody.bar_rect = new Rectangle(this.ClientRectangle.X + font_metrics.GetFontStereotypesMargim(), this.ClientRectangle.Y + font_metrics.GetFontStereotypesMargim(), this.ClientRectangle.Width - font_metrics.GetFontStereotypesMargim() * 2, this.ClientRectangle.Height - font_metrics.GetFontStereotypesMargim() * 2);
                this.toggleSwitchBody.slide_off_rect = new Rectangle(this.ClientRectangle.X + font_metrics.GetFontStereotypesMargim() * 2, this.ClientRectangle.Y + font_metrics.GetFontStereotypesMargim() * 2, slide_width, slide_height);
                this.toggleSwitchBody.slide_on_rect = new Rectangle(this.ClientRectangle.Right - font_metrics.GetFontStereotypesMargim() * 2 - slide_width, this.ClientRectangle.Y + font_metrics.GetFontStereotypesMargim() * 2, slide_width, slide_height);
            }
            this.toggleSwitchBody.slide_current_rect = this.IsOn ? this.toggleSwitchBody.slide_on_rect : this.toggleSwitchBody.slide_off_rect;
        }

        /// <summary>
        /// 设置相反状态
        /// </summary>
        public void Toggle()
        {
            this.IsOn = !this.IsOn;
        }

        /// <summary>
        /// 更改开关状态（不会触发 Toggleing、Toggled 事件）
        /// </summary>
        /// <param name="value">是否为开启状态</param>
        public void UpdateStatus(bool value)
        {
            if (this.isOn == value)
                return;

            if (this.slideing)
            {
                MainThreadAnimationControl.AnimationStop(this);
                this.slideing = false;
                this.usedTime = 0;
            }
            this.isOn = value;
            this.InitializeElement();
            this.Invalidate();
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 根据设置获取控件size
        /// </summary>
        /// <returns></returns>
        private Size GetControlAutoSize()
        {
            NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);
            int scale_font_occupied_height = font_metrics.GetFontStereotypesHeight();//字体占位高度，包括下划线和字体顶部补回空隙
            int control_height = font_metrics.GetFontStereotypesMargim() * 2 + scale_font_occupied_height + font_metrics.GetFontStereotypesMargim() * 2;
            if (this.StylePattern == ToggleSwitchStylePattern.FlatText)
            {
                int slide_width = (int)Math.Ceiling(scale_font_occupied_height * 1.1f);

                IntPtr hDC = IntPtr.Zero;
                Graphics g = null;
                ControlHelper.GetWindowClientGraphics(this.Handle, out g, out hDC);

                slide_width = Math.Max(slide_width, (int)Math.Ceiling(g.MeasureString(this.OffText, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width) + font_metrics.GetFontStereotypesMargim() * 2);
                slide_width = Math.Max(slide_width, (int)Math.Ceiling(g.MeasureString(this.OnText, this.Font, int.MaxValue, StringFormat.GenericTypographic).Width) + font_metrics.GetFontStereotypesMargim() * 2);

                g.Dispose();
                NativeMethods.ReleaseDC(this.Handle, hDC);

                return new Size(font_metrics.GetFontStereotypesMargim() * 2 + slide_width + font_metrics.GetFontStereotypesMargim() + slide_width + font_metrics.GetFontStereotypesMargim() * 2, control_height);
            }
            else
            {
                return new Size((int)(control_height * 1.9f), control_height);
            }
        }

        /// <summary>
        /// 设置控件状态
        /// </summary>
        private void SetState()
        {
            CancelEventArgs arg = new CancelEventArgs(false);
            this.OnToggleing(arg);
            if (arg.Cancel)
            {
                return;
            }

            if (this.slideing)
            {
                this.usedTime = this.allTime - this.usedTime;
            }
            else
            {
                this.usedTime = 0;
            }
            this.slideing = true;
            this.isOn = !this.isOn;
            this.toggleSwitchBody.slide_prepare_rect = this.toggleSwitchBody.slide_current_rect;
            MainThreadAnimationControl.AnimationStart(this);

            this.OnToggled(EventArgs.Empty);
        }

        #endregion

        #region 类

        /// <summary>
        /// 存放ToggleSwitch信息
        /// </summary>
        private class ToggleSwitchBody
        {
            /// <summary>
            ///滑条rect 
            /// </summary>
            public Rectangle bar_rect { get; set; }
            /// <summary>
            /// 滑块关闭rect
            /// </summary>
            public Rectangle slide_off_rect { get; set; }
            /// <summary>
            /// 滑块开启rect
            /// </summary>
            public Rectangle slide_on_rect { get; set; }
            /// <summary>
            /// 滑块当前rect
            /// </summary>
            public Rectangle slide_current_rect { get; set; }
            /// <summary>
            /// 滑块动画前rect
            /// </summary>
            public Rectangle slide_prepare_rect { get; set; }
        }

        #endregion

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinActivateColor = Color.Empty;
            private readonly Color defaultActivateColor = SystemColors.Window;
            private Color activateColor = Color.Empty;
            /// <summary>
            /// 控件激活的虚线框颜色
            /// </summary>
            [Description("控件激活的虚线框颜色")]
            [PropertyOrder(-200)]
            [SkinProperty(true, false)]
            public Color ActivateColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinActivateColor;
                    }

                    if (this.activateColor != Color.Empty)
                    {
                        return this.activateColor;
                    }

                    return this.defaultActivateColor;
                }
                set
                {
                    if (this.activateColor == value)
                        return;

                    this.activateColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeActivateColor()
            {
                return this.activateColor != Color.Empty;
            }
            private void ResetActivateColor()
            {
                this.activateColor = Color.Empty;
                this.Invalidate();
            }

            private Color skinBackColor = Color.Empty;
            private readonly Color defaultBackColor = SystemColors.Control;
            private Color backColor = Color.Empty;
            /// <summary>
            /// 背景颜色
            /// </summary>
            [Description("背景颜色")]
            [PropertyOrder(-195)]
            [SkinProperty(true, true)]
            public Color BackColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore() && this.skinBackColor != Color.Empty)
                    {
                        return this.skinBackColor;
                    }

                    if (this.backColor != Color.Empty)
                    {
                        return this.backColor;
                    }

                    if (((Control)this.owner).Parent != null)
                    {
                        return ((Control)this.owner).Parent.BackColor;
                    }

                    return this.defaultBackColor;
                }
                set
                {
                    if (this.backColor == value)
                        return;

                    this.backColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeBackColor()
            {
                return this.backColor != Color.Empty;
            }
            private void ResetBackColor()
            {
                this.backColor = Color.Empty;
                this.Invalidate();
            }

            private StateAppearanceObject off;
            /// <summary>
            /// 关闭状态样式
            /// </summary>
            [Description("关闭状态样式")]
            [PropertyOrder(-190)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public StateAppearanceObject Off
            {
                get
                {
                    if (this.off == null)
                        this.off = new StateAppearanceObject(this.owner, this
                            , SystemColors.GradientInactiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.InactiveBorder
                            , SystemColors.InactiveCaption
                            );
                    return this.off;
                }
            }

            private StateAppearanceObject on;
            /// <summary>
            /// 开启状态样式
            /// </summary>
            [Description("开启状态样式")]
            [PropertyOrder(-186)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public StateAppearanceObject On
            {
                get
                {
                    if (this.on == null)
                        this.on = new StateAppearanceObject(this.owner, this
                            , SystemColors.GradientInactiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.InactiveBorder
                            , SystemColors.InactiveCaption
                            );
                    return this.on;
                }
            }

            #endregion

            public class StateAppearanceObject : AppearanceObjectBase
            {
                internal StateAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color trackBackNormalColor, Color thumbBackNormalColor, Color trackBackDisabledColor, Color thumbBackDisabledColor) : base(owner, parent)
                {
                    this.trackBackNormalColor = trackBackNormalColor;
                    this.thumbBackNormalColor = thumbBackNormalColor;
                    this.trackBackDisabledColor = trackBackDisabledColor;
                    this.thumbBackDisabledColor = thumbBackDisabledColor;
                }

                #region 属性

                private Color trackBackNormalColor = Color.Empty;
                private Color thumbBackNormalColor = Color.Empty;
                private ItemAppearanceObject normal;
                /// <summary>
                /// 正常状态
                /// </summary>
                [Description("正常状态")]
                [Category("杂项")]
                [PropertyOrder(-194)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Normal
                {
                    get
                    {
                        if (this.normal == null)
                            this.normal = new ItemAppearanceObject(this.owner, this, this.trackBackNormalColor, this.thumbBackNormalColor);
                        return this.normal;
                    }
                }

                private Color trackBackDisabledColor = Color.Empty;
                private Color thumbBackDisabledColor = Color.Empty;
                private ItemAppearanceObject disabled;
                /// <summary>
                /// 禁用状态
                /// </summary>
                [Description("禁用状态")]
                [Category("杂项")]
                [PropertyOrder(-190)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Disabled
                {
                    get
                    {
                        if (this.disabled == null)
                            this.disabled = new ItemAppearanceObject(this.owner, this, this.trackBackDisabledColor, this.thumbBackDisabledColor);
                        return this.disabled;
                    }
                }

                #endregion

                public class ItemAppearanceObject : AppearanceObjectBase
                {
                    internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color trackBackColor, Color thumbBackColor) : base(owner, parent)
                    {
                        this.defaultTrackBackColor = trackBackColor;
                        this.defaultThumbBackColor = thumbBackColor;
                    }

                    #region 属性

                    private Color skinTrackBackColor = Color.Empty;
                    private Color defaultTrackBackColor = Color.Empty;
                    private Color trackBackColor = Color.Empty;
                    /// <summary>
                    /// 轨道颜色
                    /// </summary>
                    [Description("轨道颜色")]
                    [PropertyOrder(-159)]
                    [SkinProperty(true, false)]
                    public Color TrackBackColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinTrackBackColor;
                            }

                            if (this.trackBackColor != Color.Empty)
                            {
                                return this.trackBackColor;
                            }

                            return this.defaultTrackBackColor;
                        }
                        set
                        {
                            if (this.trackBackColor == value)
                                return;

                            this.trackBackColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeTrackBackColor()
                    {
                        return this.trackBackColor != Color.Empty;
                    }
                    private void ResetTrackBackColor()
                    {
                        this.trackBackColor = Color.Empty;
                    }

                    private Color skinThumbBackColor = Color.Empty;
                    private Color defaultThumbBackColor = Color.Empty;
                    private Color thumbBackColor = Color.Empty;
                    /// <summary>
                    /// 拇指颜色
                    /// </summary>
                    [Description("拇指颜色")]
                    [PropertyOrder(-158)]
                    [SkinProperty(true, false)]
                    public Color ThumbBackColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinThumbBackColor;
                            }

                            if (this.thumbBackColor != Color.Empty)
                            {
                                return this.thumbBackColor;
                            }

                            return this.defaultThumbBackColor;
                        }
                        set
                        {
                            if (this.thumbBackColor == value)
                                return;

                            this.thumbBackColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeThumbBackColor()
                    {
                        return this.thumbBackColor != Color.Empty;
                    }
                    private void ResetThumbBackColor()
                    {
                        this.thumbBackColor = Color.Empty;
                    }

                    #endregion

                }
            }

        }

        #endregion

    }
}
